"""
Handlers for Hames
"""
import sys
import json
import time
import traceback

import webapp2

from hames.discovery import TestDiscovery

STYLE = """
<style>
body {font-family: Geneva, Tahoma; font-size: 10px;}
p.desc {padding: 0 0 0 0; margin: 0 0 10px 0;}
td {font-family: Geneva, Tahoma; font-size: 10px;}
</style>
"""

def import_string(import_name, silent=False):
    """Imports an object based on a string in dotted notation.

    Simplified version of the function with same name from `Werkzeug`_.

    :param import_name:
        String in dotted notation of the object to be imported.
    :param silent:
        If True, import or attribute errors are ignored and None is returned
        instead of raising an exception.
    :returns:
        The imported object.
    """
    # import_name = _to_utf8(import_name)
    try:
        if '.' in import_name:
            module, obj = import_name.rsplit('.', 1)
            return getattr(__import__(module, None, None, [obj]), obj)
        else:
            return __import__(import_name)
    except (ImportError, AttributeError), e:
        if not silent:
            raise ImportStringError(import_name, e), None, sys.exc_info()[2]

class TestHandler(webapp2.RequestHandler):
    def get(self, testname=None):
        if not testname:
            abort(400, 'testname is required')
        ft_class = import_string(testname)
        if self.request.params.get('submit'):
            form = ft_class.FORM_CLASS(self.request.params)
            if form.validate():
                try:
                    ft = ft_class()
                    stime = time.time()
                    data = ft.process(form)
                    etime = time.time()
                    result = {'status': 'ok', 'elapsed_ms': int((etime-stime)*1000.0),
                              'data': data, 'messages': ft.messages}
                except Exception:
                    exc_info = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
                    result = {'status': 'error', 'exception': exc_info, 'messages': ft.messages}
                self.response.content_type = 'application/json'
                self.response.out.write(json.dumps(result))
            else:
                self.render_form(form, ft_class)
        else:
            form = ft_class.FORM_CLASS()
            self.render_form(form, ft_class)

    def render_form(self, form, ft_class):
        """ Output the form to the screen. """
        td = TestDiscovery()
        self.response.out.write("""
<html>
<head>
<title>Hames - %(appid)s - %(testname)s</title>
%(style)s
</head>
<body>
<h1>Hames - %(appid)s - %(testname)s</h1>
<a href='/hames/'>All tests</a><br/><br/>
<form method='GET'>
<table>
""" % {'appid': td.appid, 'testname': ft_class.screen_name(), 'style': STYLE})

        for field in form:
            errors = ''
            if field.errors:
                errors = '<br/>'.join(field.errors)
            self.response.out.write("""
<tr><td>%s</td><td>%s</td><td>%s</td></tr>
""" % (field.label, field(), errors))

        self.response.out.write("""
</table>
<input type='submit' name='submit' value='Submit'/>
</body>
</html>
""")

class DashboardHandler(webapp2.RequestHandler):
    def get(self, category=None):
        td = TestDiscovery()
        # test_classes = td.test_classes
        self.response.out.write("""<html>
<head>
<title>Hames - %(appid)s</title>
%(style)s
</head>
<body>
<h1>Hames - %(appid)s</h1>
""" % {'appid': td.appid, 'style': STYLE})

        last_category = None
        # import logging
        # logging.critical(td.collated_test_categories)
        for category, test_classes in td.collated_test_categories:
            if category and category != last_category:
                self.response.out.write('<h4>%s</h4>' % category)
                last_category = category
            self.response.out.write('<ul>')
            for tc in test_classes:
                self.response.out.write("""
<li><a href='/hames/ft/%s'>%s</a>
""" % (tc.url_name(), tc.screen_name()))
                if tc.description():
                    self.response.out.write('<p class="desc"><em>%s</em></p>' % tc.description())
                self.response.out.write("""</li>""")
            self.response.out.write('</ul>')

        self.response.out.write("""
</body>
</html>
""")
